package com.qzsoft.zhjd.materiel.modules.materielsupplier.service.impl;

import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletResponse;

import org.apache.poi.hssf.usermodel.DVConstraint;
import org.apache.poi.hssf.usermodel.HSSFDataValidation;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellRangeAddressList;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qzsoft.jeemis.common.utils.ConvertDictUtils;
import com.qzsoft.jeemis.platform.security.user.SecurityUser;
import com.qzsoft.jeemis.platform.security.user.UserDetail;
import com.qzsoft.jeemis.repository.sys.entity.BasicCodeitemEntity;
import com.qzsoft.system.modules.sys.dict.service.SysDictService;
import com.qzsoft.system.modules.zhjdsysdept.entity.ZhjdSysDeptEntity;
import com.qzsoft.system.modules.zhjdsysdept.service.ZhjdSysDeptService;
import com.qzsoft.zhjd.common.annotation.ZhjdDataFilter;
import com.qzsoft.zhjd.common.components.BaseServiceComponent;
import com.qzsoft.zhjd.common.enums.BizCode;
import com.qzsoft.zhjd.common.enums.YesOrNo;
import com.qzsoft.zhjd.common.excel.ZhjdExcelExportUtils;
import com.qzsoft.zhjd.common.excel.style.ZhjdExcelExportStyler;
import com.qzsoft.zhjd.common.excel.style.ZhjdExcelExportTemplateStyler;
import com.qzsoft.zhjd.common.utils.RenExceptionUtils;
import com.qzsoft.zhjd.materiel.modules.materieldata.entity.MaterielDataEntity;
import com.qzsoft.zhjd.materiel.modules.materieldata.service.MaterielDataService;
import com.qzsoft.zhjd.materiel.modules.materielsupplier.dto.MaterielSupplierExcelDto;
import com.qzsoft.zhjd.materiel.modules.materielsupplier.dto.MaterielSupplierImportDto;
import com.qzsoft.zhjd.materiel.modules.materielsupplier.dto.MaterielSupplierListDto;
import com.qzsoft.zhjd.materiel.modules.materielsupplier.entity.MaterielSupplierEntity;
import com.qzsoft.zhjd.materiel.modules.materielsupplier.mapper.MaterielSupplierMapper;
import com.qzsoft.zhjd.materiel.modules.materielsupplier.service.MaterielSupplierService;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.ImportParams;

/**
 * @ClassName MaterielSupplierServiceImpl
 * @Description 供应商业务接口实现
 * @author linhuawei
 * @since 2022-03-30
 */
@Service
public class MaterielSupplierServiceImpl extends ServiceImpl<MaterielSupplierMapper, MaterielSupplierEntity>
        implements MaterielSupplierService {

    @Autowired
    private BaseServiceComponent baseServiceComponent;

    @Autowired
    private MaterielDataService materielDataService;

//    @Autowired
//    private MaterielApiService materielApiService;

    @Autowired
    private SysDictService sysDictService;

    @Autowired
    private ZhjdSysDeptService zhjdSysDeptService;

//    @Autowired
//    private MaterielSupplierService  materielSupplierService;
//
//    @Value("${zhjd.upload.getSupplier}")
//    private String getSupplier;

    @Override
    @ZhjdDataFilter(tableAlias = "t1")
    public IPage<MaterielSupplierListDto> page(Map<String, Object> params) {
        IPage<MaterielSupplierListDto> page = baseServiceComponent.getPage(params, MaterielSupplierListDto.class);
        IPage<MaterielSupplierListDto> dataPage = baseMapper.queryDto(page, params);
        return ConvertDictUtils.formatDicDataPage(dataPage);
    }

    @Override
    @ZhjdDataFilter
    public List<MaterielSupplierEntity> list(Map<String, Object> params) {
        QueryWrapper<MaterielSupplierEntity> queryWrapper = new QueryWrapper<MaterielSupplierEntity>();
        if (ObjectUtils.isNotEmpty(params.get("baseCode"))) {
            queryWrapper.eq("base_code", params.get("baseCode").toString());
        }
        if (ObjectUtils.isNotEmpty(params.get(ZhjdDataFilter.DATA_FILTER_SQL))) {
            queryWrapper.apply(params.get(ZhjdDataFilter.DATA_FILTER_SQL).toString());
        }
        queryWrapper.orderByAsc("base_code, name");
        return baseMapper.selectList(queryWrapper);
    }

    @Override
    public List<MaterielSupplierEntity> getByBaseCode(String baseCode) {
        QueryWrapper<MaterielSupplierEntity> queryWrapper = new QueryWrapper<MaterielSupplierEntity>();
        queryWrapper.eq("base_code", baseCode);
        queryWrapper.orderByAsc("base_code, name");
        return baseMapper.selectList(queryWrapper);
    }

    @Override
    public boolean save(MaterielSupplierEntity entity) {
        // 判断供应商名称是否重复
        checkName(entity);

        // 默认启用状态
        entity.setEnable(YesOrNo.yes.getValue());
        return super.save(entity);
    }

    @Override
    public boolean updateById(MaterielSupplierEntity entity) {
        // 判断供应商名称是否重复
        checkName(entity);

        // 执行修改操作
        return super.updateById(entity);
    }

    @Override
    public void updateEnable(String id, YesOrNo enable) {
        UserDetail user = SecurityUser.getUser();
        UpdateWrapper<MaterielSupplierEntity> updateWrapper = new UpdateWrapper<MaterielSupplierEntity>();
        updateWrapper.set("enable", enable.getValue());
        updateWrapper.set("updater", user.getId());
        updateWrapper.set("update_date", new Date());
        updateWrapper.eq("id", id);
        baseMapper.update(null, updateWrapper);
    }

    @Override
    public boolean removeById(Serializable id) {
        // 判断供应商是否使用中，使用中不可删除
        QueryWrapper<MaterielDataEntity> queryWrapper = new QueryWrapper<MaterielDataEntity>();
        queryWrapper.eq("supplier_id", id);
        Integer count = materielDataService.count(queryWrapper);
        if (null != count && 0 < count) {
            RenExceptionUtils.throwEx(BizCode.PARAMS_ERROR, "供应商已经使用，不可删除");
        }

        // 执行删除操作
        return super.removeById(id);
    }

    @Override
    @ZhjdDataFilter(tableAlias = "t1")
    public void export(Map<String, Object> params, HttpServletResponse response) {
        List<MaterielSupplierExcelDto> dataList = baseMapper.queryExcelDto(params);
        List<MaterielSupplierExcelDto> list = ConvertDictUtils.formatDicDataList(dataList);
        String fileName = "供应商";
        ExportParams exportParams = new ExportParams(null, fileName);
        exportParams.setFixedTitle(false);
        exportParams.setStyle(ZhjdExcelExportStyler.class);
        try {
            ZhjdExcelExportUtils.exportExcel(response, fileName, exportParams, MaterielSupplierExcelDto.class, list);
        } catch (IOException e) {
            log.error("供应商导出失败：{}", e);
            RenExceptionUtils.throwEx("数据导出失败");
        }
    }

    @Override
    public void template(HttpServletResponse response) {
        // 获取数据字典
        List<BasicCodeitemEntity> unitNature = sysDictService.listByCodeid("COMPANY_TYPE");
        String[] unitNatureArray = new String[unitNature.size()];
        BasicCodeitemEntity item;
        for (int i = 0, len = unitNature.size(); i < len; i++) {
            item = unitNature.get(i);
            unitNatureArray[i] = item.getDescription();
        }

        List<BasicCodeitemEntity> qualificationLevel = sysDictService.listByCodeid("COMPANY_QUALIFICATION");
        String[] qualificationLevelArray = new String[qualificationLevel.size()];
        for (int i = 0, len = qualificationLevel.size(); i < len; i++) {
            item = qualificationLevel.get(i);
            qualificationLevelArray[i] = item.getDescription();
        }

        List<BasicCodeitemEntity> taxpayerCategory = sysDictService.listByCodeid("TAX_PAYER_CATEGORY");
        String[] taxpayerCategoryArray = new String[taxpayerCategory.size()];
        for (int i = 0, len = taxpayerCategory.size(); i < len; i++) {
            item = taxpayerCategory.get(i);
            taxpayerCategoryArray[i] = item.getDescription();
        }

        List<BasicCodeitemEntity> evaluationGrade = sysDictService.listByCodeid("COMPANY_EVALUATION_GRADE");
        String[] evaluationGradeArray = new String[evaluationGrade.size()];
        for (int i = 0, len = evaluationGrade.size(); i < len; i++) {
            item = evaluationGrade.get(i);
            evaluationGradeArray[i] = item.getDescription();
        }

        List<BasicCodeitemEntity> evaluationStatus = sysDictService.listByCodeid("COMPANY_EVALUATION_STATUS");
        String[] evaluationStatusArray = new String[evaluationStatus.size()];
        for (int i = 0, len = evaluationStatus.size(); i < len; i++) {
            item = evaluationStatus.get(i);
            evaluationStatusArray[i] = item.getDescription();
        }

        List<MaterielSupplierImportDto> list = new ArrayList<MaterielSupplierImportDto>();
        String fileName = "供应商导入模板";
        ExportParams exportParams = new ExportParams(null, fileName);
        exportParams.setFixedTitle(false);
        exportParams.setStyle(ZhjdExcelExportTemplateStyler.class);

        Workbook workbook = ExcelExportUtil.exportExcel(exportParams, MaterielSupplierImportDto.class, list);
        Sheet sheet = workbook.getSheetAt(0);
        int lastRow = 65535;
        CellRangeAddressList regions = new CellRangeAddressList(1, lastRow, 3, 3);
        DVConstraint constraint = DVConstraint.createExplicitListConstraint(unitNatureArray);
        HSSFDataValidation dataValidation = new HSSFDataValidation(regions, constraint);
        sheet.addValidationData(dataValidation);

        regions = new CellRangeAddressList(1, lastRow, 5, 5);
        constraint = DVConstraint.createExplicitListConstraint(qualificationLevelArray);
        dataValidation = new HSSFDataValidation(regions, constraint);
        sheet.addValidationData(dataValidation);

        regions = new CellRangeAddressList(1, lastRow, 6, 6);
        constraint = DVConstraint.createExplicitListConstraint(taxpayerCategoryArray);
        dataValidation = new HSSFDataValidation(regions, constraint);
        sheet.addValidationData(dataValidation);

        regions = new CellRangeAddressList(1, lastRow, 7, 7);
        constraint = DVConstraint.createExplicitListConstraint(evaluationGradeArray);
        dataValidation = new HSSFDataValidation(regions, constraint);
        sheet.addValidationData(dataValidation);

        regions = new CellRangeAddressList(1, lastRow, 8, 8);
        constraint = DVConstraint.createExplicitListConstraint(evaluationStatusArray);
        dataValidation = new HSSFDataValidation(regions, constraint);
        sheet.addValidationData(dataValidation);

//        sheet.setDefaultRowHeightInPoints(24);
//        sheet.setHorizontallyCenter(true);
//        sheet.setVerticallyCenter(true);

        try {
            ZhjdExcelExportUtils.exportExcel(response, fileName, workbook);
        } catch (Exception e) {
            log.error("供应商模板导出失败：{}", e);
            RenExceptionUtils.throwEx("数据导出失败");
        }
    }

    @Override
    public List<MaterielSupplierImportDto> importExcel(String baseCode, MultipartFile file) {
        // 判断基地是否存在
        ZhjdSysDeptEntity dept = zhjdSysDeptService.getBaseByCode(baseCode);
        if (null == dept) {
            RenExceptionUtils.throwEx(BizCode.PARAMS_ERROR, "基地不存在");
        }

        // 解析excel文件
        List<MaterielSupplierImportDto> list = null;
        try {
            ImportParams params = new ImportParams();
            list = ExcelImportUtil.importExcel(file.getInputStream(), MaterielSupplierImportDto.class, params);
        } catch (Exception e) {
            log.error("供应商导入失败：{}", e);
            RenExceptionUtils.throwEx("供应商导入失败");
        }
        if (null == list || 0 == list.size()) {
            RenExceptionUtils.throwEx("供应商信息不存在");
        }

        // 获取数据字典
        List<BasicCodeitemEntity> unitNature = sysDictService.listByCodeid("COMPANY_TYPE");
        Map<String, String> unitNatureMap = new HashMap<String, String>();
        for (BasicCodeitemEntity item : unitNature) {
            unitNatureMap.put(item.getDescription(), item.getCode());
        }

        List<BasicCodeitemEntity> qualificationLevel = sysDictService.listByCodeid("COMPANY_QUALIFICATION");
        Map<String, String> qualificationLevelMap = new HashMap<String, String>();
        for (BasicCodeitemEntity item : qualificationLevel) {
            qualificationLevelMap.put(item.getDescription(), item.getCode());
        }

        List<BasicCodeitemEntity> taxpayerCategory = sysDictService.listByCodeid("TAX_PAYER_CATEGORY");
        Map<String, String> taxpayerCategoryMap = new HashMap<String, String>();
        for (BasicCodeitemEntity item : taxpayerCategory) {
            taxpayerCategoryMap.put(item.getDescription(), item.getCode());
        }

        List<BasicCodeitemEntity> evaluationGrade = sysDictService.listByCodeid("COMPANY_EVALUATION_GRADE");
        Map<String, String> evaluationGradeMap = new HashMap<String, String>();
        for (BasicCodeitemEntity item : evaluationGrade) {
            evaluationGradeMap.put(item.getDescription(), item.getCode());
        }

        List<BasicCodeitemEntity> evaluationStatus = sysDictService.listByCodeid("COMPANY_EVALUATION_STATUS");
        Map<String, String> evaluationStatusMap = new HashMap<String, String>();
        for (BasicCodeitemEntity item : evaluationStatus) {
            evaluationStatusMap.put(item.getDescription(), item.getCode());
        }

        // 数据校验
        Set<String> nameSet = new HashSet<String>();
        Integer count;
        QueryWrapper<MaterielSupplierEntity> queryWrapper = new QueryWrapper<MaterielSupplierEntity>();
        List<MaterielSupplierEntity> entityList = new ArrayList<MaterielSupplierEntity>();
        MaterielSupplierEntity entity = new MaterielSupplierEntity();
        for (MaterielSupplierImportDto dto : list) {
            // 判断名称是否存在
            if (ObjectUtils.isEmpty(dto.getName())) {
                dto.setSuccess(false);
                dto.setErrorMesg("供应商名称为空");
                continue;
            }

            // 判断是否重名
            if (nameSet.contains(dto.getName())) {
                dto.setSuccess(false);
                dto.setErrorMesg("供应商名称重复");
                continue;
            }

            // 判断是否已经存在
            queryWrapper.clear();
            queryWrapper.eq("base_code", baseCode);
            queryWrapper.eq("name", dto.getName());
            count = baseMapper.selectCount(queryWrapper);
            if (null != count && 0 < count) {
                dto.setSuccess(false);
                dto.setErrorMesg("供应商名称重复");
                continue;
            }

            // TODO 判断字典数据?
            entity = new MaterielSupplierEntity();
            BeanUtils.copyProperties(dto, entity);
            entity.setBaseCode(baseCode);
            entity.setUnitNature(unitNatureMap.get(dto.getUnitNatureLabel()));
            entity.setQualificationLevel(qualificationLevelMap.get(dto.getQualificationLevelLabel()));
            entity.setTaxpayerCategory(taxpayerCategoryMap.get(dto.getTaxpayerCategoryLabel()));
            entity.setEvaluationGrade(evaluationGradeMap.get(dto.getEvaluationGradeLabel()));
            entity.setEvaluationStatus(evaluationStatusMap.get(dto.getEvaluationStatusLabel()));
            entity.setEnable(YesOrNo.yes.getValue());
            entityList.add(entity);
            dto.setSuccess(true);
        }

        // 执行添加操作
        this.saveBatch(entityList, 100);

        // 返回导入结果
        return list;
    }

//    @Override
//    @Transactional(rollbackFor = Exception.class)
//    public void getUrlInfo() throws IOException {
//        //删除表中数据
//        materielSupplierService.remove(null);
//        //获取登录用户信息
//        UserDetail user = SecurityUser.getUser();
//        //获取访问接口的url
//        String url = getSupplier;
//        //初始化访问客户端
//        CloseableHttpClient httpclient = HttpClients.createDefault();
//        HttpGet httpGet = new HttpGet(url);
//        //给head中的getWeightType赋版本值
//        QueryWrapper apiVersion = new QueryWrapper<MaterielApiVesionEntity>();
//        apiVersion.eq("code","getCooperates");
////        MaterielApiVesionEntity apiVersionEntity = materielApiService.getOne(apiVersion);
////        httpGet.setHeader("getCooperates",String.valueOf(apiVersionEntity.getVersion()));
//        //执行访问
//        CloseableHttpResponse responses = httpclient.execute(httpGet);
//        //获取响应码
//        Integer num = responses.getStatusLine().getStatusCode();
//        if(num >= 400 && num < 500){
//            RenExceptionUtils.throwEx("接口错误！");
//        }
//        if(num >= 500 && num < 600){
//            RenExceptionUtils.throwEx(BizCode.EXCEPTION, "调用接口内部异常");
//        }
//        //获取返回数据
//        HttpEntity entity  = responses.getEntity();
//        String entityString = EntityUtils.toString(entity);
//        JSONObject datas = JSONObject.parseObject(entityString);
//        Object info = datas.get("data");
//        //更新version
//        Object version = datas.get("version");
//        Long Version = Long.parseLong(String.valueOf(version));
////        apiVersionEntity.setVersion(Version);
////        materielApiService.update(apiVersionEntity,apiVersion);
//        //处理响应数据，存储过磅类型数据
//        if(info instanceof List) {
//            for(Object record :(List) info){
//                if(record instanceof Map){
//                    //供应商类型
//                    Object type = ((Map) record).get("type");
//                    //供应商名称
//                    Object name = ((Map) record).get("name");
//                    //联系人
//                    Object businessLicenseNo = ((Map) record).get("businessLicenseNo");
//                    // 注册资金
//                    Object registeredCapital = ((Map) record).get("registeredCapital");
//
//                    MaterielSupplierEntity materielSupplierEntity = new MaterielSupplierEntity();
//
//                    materielSupplierEntity.setName(String.valueOf(name));
//                    if(registeredCapital != null) {
//                        materielSupplierEntity.setRegisteredCapital(BigDecimal.valueOf(Long.valueOf(String.valueOf(registeredCapital))));
//                    }
//
//                    if(businessLicenseNo != null) {
//                        materielSupplierEntity.setUnifiedSocialCreditCode((String.valueOf(registeredCapital)));
//                    }
//                    materielSupplierService.save(materielSupplierEntity);
//                }
//            }
//        }
//    }

    /**
     * @Title checkName
     * @Description 校验供应商名称
     * @param entity
     */
    private void checkName(MaterielSupplierEntity entity) {
        QueryWrapper<MaterielSupplierEntity> queryWrapper = new QueryWrapper<MaterielSupplierEntity>();
        queryWrapper.eq("base_code", entity.getBaseCode());
        queryWrapper.eq("name", entity.getName());
        if (ObjectUtils.isNotEmpty(entity.getId())) {
            queryWrapper.ne("id", entity.getId());
        }
        Integer count = baseMapper.selectCount(queryWrapper);
        if (null != count && 0 < count) {
            RenExceptionUtils.throwEx(BizCode.PARAMS_ERROR, "供应商[" + entity.getName() + "]已经存在");
        }
    }

}
